package com.ajk.server.controller.shop;

import java.io.BufferedReader;
import java.io.IOException;
import java.security.Principal;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.ajk.server.exception.AjkException;
import com.ajk.server.exception.ErrorConstant;
import com.ajk.server.model.Pay;
import com.ajk.server.model.response.Result;
import com.ajk.server.model.response.ResultList;
import com.ajk.server.model.response.ResultObject;
import com.ajk.server.security.AjkUserDetails;
import com.ajk.server.service.PayService;
import com.ajk.server.utils.AjkUtil;
import com.ajk.shop.model.ImputedPrice;
import com.ajk.shop.model.UserAddress;
import com.ajk.shop.model.request.GoodsReq;
import com.ajk.shop.model.request.OrderInfoReq;
import com.ajk.shop.model.response.CategoryRes;
import com.ajk.shop.model.response.GoodsRes;
import com.ajk.shop.model.response.OrderInfoRes;
import com.ajk.shop.service.GoodsService;
import com.ajk.shop.service.OrderService;
import com.ajk.shop.service.UserAddressService;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Event;
import com.pingplusplus.model.Webhooks;

@RestController
@RequestMapping("/shop")
public class ShopController {
	private final static Logger logger = LoggerFactory.getLogger(ShopController.class);
	
	@Autowired
	private GoodsService goodsService;
	
	@Autowired
	private UserAddressService userAddressService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private PayService payService;
	/**
	 * 首页
	 * @param goodReq
	 * @return
	 */
	@RequestMapping(value="/home/goods/list")
	public ResultList<CategoryRes> homeList(GoodsReq goodReq){
		
		List<CategoryRes> list = goodsService.getHomeList(goodReq);
		
		return new ResultList<CategoryRes>(list);
	}
	/**
	 * 首页Banner列表
	 * @param goodReq
	 * @return
	 */
	@RequestMapping(value="/home/banner/list")
	public ResultList<CategoryRes> homeBanner(GoodsReq goodReq){
		
		List<CategoryRes> list = goodsService.getBannerList(goodReq);
		
		return new ResultList<CategoryRes>(list);
	}
	
	/**
	 * 商品分类列表
	 * @param goodReq
	 * @return
	 */
	@RequestMapping(value="/category/list")
	public ResultList<CategoryRes> categroyList(GoodsReq goodReq){
		
		List<CategoryRes> list = goodsService.categoryList();
		
		return new ResultList<CategoryRes>(list);
	}
	
	/**
	 * 商品详情
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/goods/detail/{id}")
	public ResultObject<GoodsRes> goodsDetail(@PathVariable("id") Integer id){
		GoodsReq gr = new GoodsReq();
		gr.setId(id);
		GoodsRes goodsRes = goodsService.goodsDetail(gr);
		
		return new ResultObject<GoodsRes>(goodsRes);
	}
	
	/**
	 * 商品详情
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/goods/list")
	public ResultList<GoodsRes> goodsList(GoodsReq goodsReq){
		if(goodsReq.getLimit() == null || goodsReq.getLimit() <= 0){
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "limit 不能为空");
		}
		List<GoodsRes> goodsRes = goodsService.goodsList(goodsReq);
		
		return new ResultList<GoodsRes>(goodsRes);
	}
	
	/**
	 * 新增收货地址
	 * @param principal
	 * @param userAddress
	 * @return
	 */
	@RequestMapping(value="/address/add")
	public ResultObject<UserAddress> addAddress(Principal principal,@RequestBody UserAddress userAddress){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		userAddress.setUserId(userDetails.getUserId());
		
		return new ResultObject<UserAddress>(userAddressService.addUserAddress(userAddress));
	}
	
	/**
	 * 修改收货地址
	 * @param principal
	 * @param userAddress
	 * @return
	 */
	@RequestMapping(value="/address/modify")
	public ResultObject<UserAddress> modifyAddress(Principal principal,@RequestBody UserAddress userAddress){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		userAddress.setUserId(userDetails.getUserId());
		
		return new ResultObject<UserAddress>(userAddressService.modifyUserAddress(userAddress));
	}
	
	/**
	 * 商品详情
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/address/default")
	public ResultObject<UserAddress> addAddress(Principal principal){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		UserAddress userAddress = userAddressService.getUserAddressByDefault(userDetails.getUserId());
		return new ResultObject<UserAddress>(userAddress);
	}
	
	/**
	 * 商品详情
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/address/all")
	public ResultList<UserAddress> allAddress(Principal principal){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		List<UserAddress>  list = userAddressService.getUserAddressAll(userDetails.getUserId());
		return new ResultList<UserAddress>(list);
	}
	
	/**
	 * 删除收货地址
	 * @param principal
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/address/delete/{id}",method=RequestMethod.PUT)
	public Result deleteAddress(Principal principal,@PathVariable("id") Integer id){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		if(null == id || id <= 0){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "ID不能为空");
		}
		userAddressService.deleteUserAddress(id);
		return new Result();
	}
	
	/**
	 * 删除收货地址
	 * @param principal
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/address/default/{id}",method=RequestMethod.PUT)
	public Result updateAddressToDefault(Principal principal,@PathVariable("id") Integer id){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		if(null == id || id <= 0){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "ID不能为空");
		}
		UserAddress userAddress = new UserAddress();
		userAddress.setId(id);
		userAddress.setUserId(userDetails.getUserId());
		userAddressService.updateAddressToDefault(userAddress);
		return new Result();
	}
	
	/**
	 * 创建订单
	 * @param principal
	 * @param orderInfoReq
	 * @return
	 */
	@RequestMapping(value="/order/create",method=RequestMethod.POST)
	public ResultObject<OrderInfoRes> createOrder(Principal principal,@RequestBody OrderInfoReq orderInfoReq){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		orderInfoReq.setUserId(userDetails.getUserId());
		ResultObject<OrderInfoRes> resultObject = new ResultObject<OrderInfoRes>();
		resultObject.setDomain(orderService.createOrder(orderInfoReq));
		return resultObject;
	}
	
	/**
	 * 创建订单
	 * @param principal
	 * @param orderInfoReq
	 * @return
	 */
	@RequestMapping(value="/order/postage_calculate",method=RequestMethod.POST)
	public ResultObject<ImputedPrice> postageCalculate(Principal principal,@RequestBody OrderInfoReq orderInfoReq){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		orderInfoReq.setUserId(userDetails.getUserId());
		ResultObject<ImputedPrice> resultObject = new ResultObject<ImputedPrice>();
		resultObject.setDomain(orderService.calculatePostage(orderInfoReq));
		return resultObject;
	}
	
	/**
	 * 订单列表
	 * @param principal
	 * @param orderInfoReq
	 * @return
	 */
	@RequestMapping(value="/order/my/list",method=RequestMethod.GET)
	public ResultList<OrderInfoRes> orderMyList(Principal principal,OrderInfoReq orderInfoReq){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		orderInfoReq.setUserId(userDetails.getUserId());
		ResultList<OrderInfoRes> resultList = new ResultList<OrderInfoRes>();
		resultList.setItemList(orderService.userOrderList(orderInfoReq));
		return resultList;
	}
	

	/**
	 * 订单详情
	 * @param principal
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/order/detail/{id}",method=RequestMethod.GET)
	public ResultObject<OrderInfoRes> orderDetail(Principal principal,@PathVariable("id") Integer id){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		if(null == id || id <= 0){
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "订单ID不能为空"); 
		}
		ResultObject<OrderInfoRes> resultObject = new ResultObject<OrderInfoRes>();
		OrderInfoReq orderInfoReq = new OrderInfoReq();
		orderInfoReq.setUserId(userDetails.getUserId());
		orderInfoReq.setId(id);
		resultObject.setDomain(orderService.orderDetail(orderInfoReq));
		return resultObject;
	}
	
	/**
	 * 订单详情
	 * @param principal
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/order/cancel/{id}",method=RequestMethod.PUT)
	public Result cancelOrder(Principal principal,@PathVariable("id") Integer id){
		AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		if(null == id || id <= 0){
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "订单ID不能为空"); 
		}
		OrderInfoReq orderInfoReq = new OrderInfoReq();
		orderInfoReq.setUserId(userDetails.getUserId());
		orderInfoReq.setId(id);
		orderService.cancelOrder(orderInfoReq);
		return new Result();
	}
	
	/**
	 * 订单详情
	 * @param principal
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/generate/charge",method=RequestMethod.POST)
	public ResultObject<Charge> generateCharge(Principal principal,@RequestBody Pay pay,HttpServletRequest request){
		if(pay.getOrderId() == null || pay.getOrderId() <= 0){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "订单ID不能为空");
		}
		pay.setClientIp(AjkUtil.getClientIPAddress(request));
		ResultObject<Charge> resultObject = new ResultObject<Charge>();
		Charge charge = payService.generateCharge(pay);
		resultObject.setDomain(charge);
		return resultObject;
	}

	
	@RequestMapping(value="/webhooks/event",method=RequestMethod.POST)
	@ResponseBody
	public String webhookResult(HttpServletRequest request) throws IOException {
    		
		request.setCharacterEncoding("UTF8");
        BufferedReader reader = request.getReader();
        StringBuffer buffer = new StringBuffer();
        String string;
        while ((string = reader.readLine()) != null) {
            buffer.append(string);
        }
        reader.close();
        // 解析异步通知数据
        Event event = Webhooks.eventParse(buffer.toString());
        if ("charge.succeeded".equals(event.getType())) {
        	Charge charge = (Charge)Webhooks.parseEvnet(buffer.toString());
        	Map<String,String> extra = charge.getExtra();
        	String buyerAccount = null;
        	if(null != extra && !extra.isEmpty()){
        		if(charge.getChannel().equals("wx")){
        			buyerAccount = (null == extra.get("open_id") ) ? null : extra.get("open_id").toString();
        		}else if(charge.getChannel().equals("alipay")){
        			buyerAccount = (null == extra.get("buyer_account") ) ? null : extra.get("buyer_account").toString();
        		}else if(charge.getChannel().equals("alipay_wap")){
        			buyerAccount = (null == extra.get("buyer_account") ) ? null : extra.get("buyer_account").toString();
        		}
        	}else{
        		//如果回调成功,extra是空,则记录一条日志
        		logger.error("buyer_account:"+buffer.toString());
        	}
        	
        	String orderNo = charge.getOrderNo();
        	String chId = charge.getId();
        	orderService.webhookPayrSuccessCallBack(orderNo, charge.getChannel(), buyerAccount, chId);
        } else if ("refund.succeeded".equals(event.getType())) {
        	
        } else {
        	
        }
		return "OK";
	}
	
	/**
     * 确认收货
     * @param principal
     * @param OrderInfoReq
     * @return
     */
    @RequestMapping(value = "/order/confirm_receipt", method = RequestMethod.POST)
    public Result confirmReceipt(Principal principal,@RequestBody OrderInfoReq orderInfoReq) {
    	AjkUserDetails userDetails = AjkUtil.getUserDetails(principal);
		if(null == userDetails){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_LOGIN.getErrorCode(), "未登录,请先登录");
		}
		orderInfoReq.setUserId(userDetails.getUserId());
		orderService.confirmReceipt(orderInfoReq);
        return new Result();
    }

}